#!/bin/bash
LLVM_PROJECT_DIR="${PWD}/llvm-project"
LLVM_CI_DIR="${PWD}/llvm-ci"
TOOLCHAIN_PATH=$(find "${PWD}" -maxdepth 1 -type d -name 'clang-*')
TOOLCHAIN_BIN_PATH="${TOOLCHAIN_PATH}/bin"
export PATH="${TOOLCHAIN_BIN_PATH}:${PATH}"
BUILD_DIR="${PWD}"
TARGET_TRIPLE="aarch64-linux-ohos"
#EXTRA_FLAGS="-march=armv7-a"
CLANG_FLAGS="clang_flags.txt"
PHONE_MODEL_NAME="LIO ELS"
# LIFE_TIME_FARM_GROUP="7"
PHONE_GROUP_NAME="LLVM-CI"
DISABLED_TESTS="aarch64-linux-ohos-asan.txt"
PHONE_SYMBOLIZER_PATH="/system/bin/llvm-symbolizer"

export disabled_tests_dir="${LLVM_CI_DIR}/resources/disabled_tests"
export enabled_tests_dir="${LLVM_CI_DIR}/resources/enabled_tests"

pushd "${PWD}/llvm-project"
cmake -G Ninja \
      -DLLVM_ENABLE_PROJECTS='clang;clang-tools-extra;libcxx;libcxxabi;libunwind;lldb;compiler-rt;lld;polly' \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX="${PWD}/install" \
      "${LLVM_PROJECT_DIR}/llvm"
ninja install-llvm-config
export LLVM_CONFIG_PATH="${PWD}/install/bin/llvm-config"
popd
export SYSROOT="${PWD}/sysroot/${TARGET_TRIPLE}"
export RT_COMPILE_FLAGS="-v --target=${TARGET_TRIPLE} --sysroot=${SYSROOT} ${EXTRA_FLAGS}"


TMP_DIR="${BUILD_DIR}"
mkdir -p "${TMP_DIR}"
pushd "${TMP_DIR}"

cmake \
	${LLVM_PROJECT_DIR}/compiler-rt \
	-G Ninja \
	-DCMAKE_MODULE_PATH="${LLVM_CI_DIR}/resources/cmake" \
	-DCMAKE_SYSTEM_NAME=OHOS \
	-DCMAKE_AR="${TOOLCHAIN_BIN_PATH}/llvm-ar" \
	-DLLVM_CONFIG_PATH="${LLVM_CONFIG_PATH}" \
	-DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
	-DCMAKE_ASM_FLAGS="${RT_COMPILE_FLAGS}" \
	-DCMAKE_C_COMPILER="${TOOLCHAIN_BIN_PATH}/clang" \
	-DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
	-DCMAKE_C_FLAGS="${RT_COMPILE_FLAGS}" \
	-DCMAKE_CXX_COMPILER="${TOOLCHAIN_BIN_PATH}/clang++" \
	-DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
	-DCMAKE_CXX_FLAGS="${RT_COMPILE_FLAGS}" \
	-DCMAKE_EXE_LINKER_FLAGS="${RT_COMPILE_FLAGS}" \
	-DCOMPILER_RT_BUILD_BUILTINS=OFF \
	-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
	-DCOMPILER_RT_BUILD_MEMPROF=OFF \
	-DCOMPILER_RT_BUILD_PROFILE=ON \
	-DCOMPILER_RT_BUILD_SANITIZERS=ON \
	-DCOMPILER_RT_BUILD_XRAY=OFF \
	-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
	-DCOMPILER_RT_INCLUDE_TESTS=ON \
	-DCOMPILER_RT_TEST_COMPILER="${TOOLCHAIN_BIN_PATH}/clang" \
	-DCOMPILER_RT_TEST_COMPILER_CFLAGS="${RT_COMPILE_FLAGS}"

echo "RT_COMPILE_FLAGS = ${RT_COMPILE_FLAGS}" >> "${BUILD_DIR}/${CLANG_FLAGS}"

popd
ninja AsanDynamicUnitTests
ninja AsanUnitTests
export hdc="/usr/bin/hdc"
#get devices
hdc list targets

function cleanup_phone() {
       if $(echo "${TARGET_TRIPLE}" | grep -qv "x86"); then # arm64 || arm32
         cleandir="${1:?"clean dir no set"}"
         hdc shell "rm -rf ${cleandir}"
         hdc shell "rm -f ${PHONE_SYMBOLIZER_PATH}"
       fi
     }

 disabled_tests_path="${disabled_tests_dir}/${DISABLED_TESTS}"
 if [ -f "${disabled_tests_path}" ]; then
     disabled="$(cat ${disabled_tests_path} | tr '\n' '|' | sed -e "s/|$//g")"
     for dir in "${BUILD_DIR}/test/asan/"*; do
         if [ -d "${dir}" ]; then
         RUN_TESTS+="$(python3 bin/llvm-lit --show-tests ${dir} 2>/dev/null \
                 | grep "AddressSanitizer" \
                 | grep -v -E "${disabled}" \
                 | sed -e "s/  //" \
                 | tr '\n' '|')" || true
         fi
     done
     # remove trailing |
     export RUN_TESTS="$(echo "${RUN_TESTS}" | sed -e "s/|$//g")"
     echo "tests to run:"
     echo "${RUN_TESTS}"
 fi

 if $(echo "${TARGET_TRIPLE}" | grep -qv "x86"); then # arm64 || arm32
     # global-overflow-bfd.cpp test need cross-compilation with gnu-ld linker,
     # but default gnu linker doesn't support arm/aarch64 targets,
     # so we replace it with one which supports
     sudo ln -fs /usr/bin/aarch64-linux-gnu-ld /usr/bin/ld.bfd
     HOS_TMPDIR="/data/local/tmp/Output"
     hdc shell mount -o rw,remount / || EXIT_CODE=$?
     # remove artifacts from previous run, if exists
     cleanup_phone "${HOS_TMPDIR}" || EXIT_CODE=$?
     hdc shell "mkdir /data/local/tmp/Output"
     # push all libraries needed for tests
     for file in $(find "${TOOLCHAIN_PATH}" -name "libclang_rt.asan*" | grep "${TARGET_TRIPLE}/"); do
     hdc file send "${file}" "${HOS_TMPDIR}/$(basename ${file})" || EXIT_CODE=$?
     done
     hdc file send "${TOOLCHAIN_PATH}/lib/${TARGET_TRIPLE}/c++/libc++.so" "${HOS_TMPDIR}/libc++.so" || EXIT_CODE=$?

     # FileCheck expects symbolized output,
     # so we have to push llvm-symbolizer to target,
     # and make sure, that it is on PATH
     SYMBOLIZER_NAME="llvm-symbolizer-aarch64"
     hdc file send "${SYMBOLIZER_NAME}" "${HOS_TMPDIR}/${SYMBOLIZER_NAME}" || EXIT_CODE=$?
     hdc shell "chmod +x ${HOS_TMPDIR}/${SYMBOLIZER_NAME}" || EXIT_CODE=$?
     hdc shell "ln -sf ${HOS_TMPDIR}/${SYMBOLIZER_NAME} ${PHONE_SYMBOLIZER_PATH}" || EXIT_CODE=$?

     # for *-ohos targets we need ld-musl linker to run tests
     if [[ "${TARGET_TRIPLE}" =~ ohos ]]; then
     ARCH="$(echo "${TARGET_TRIPLE}" | cut -f1 -d'-')"
     LINKER_NAME="ld-musl-${ARCH}.so.1"
     LINKER="${SYSROOT}/usr/lib/${LINKER_NAME}"
     export DEVICE_MUSL_LINKER="${HOS_TMPDIR}/${LINKER_NAME}"
     hdc file send "${LINKER}" "${DEVICE_MUSL_LINKER}" || EXIT_CODE=$?
     hdc shell "chmod +x ${HOS_TMPDIR}/${LINKER_NAME}"
     else
     # for *-hos targets we need to copy libm.so
     hdc file send "${SYSROOT}/usr/lib/libm.so" "${HOS_TMPDIR}/libm.so"
     fi
 fi


 TARGET_UNIT_TEST_DIR="${HOS_TMPDIR}/Unit"
 hdc shell mkdir -p "${TARGET_UNIT_TEST_DIR}" || EXIT_CODE=$?
 LOCAL_UNIT_TEST_DIRS="${PWD}/lib/asan/tests/default ${PWD}/lib/asan/tests/dynamic"
 for unit_dir in ${LOCAL_UNIT_TEST_DIRS}; do
       hdc file send ${unit_dir}/* "${TARGET_UNIT_TEST_DIR}" || EXIT_CODE=$?
     done
     for unit_dir in ${LOCAL_UNIT_TEST_DIRS}; do
       for test in ${unit_dir}/*; do
         testname="$(basename "${test}")"
         unittest_disabled="${disabled_tests_dir}/${testname}-${TARGET_TRIPLE}.txt"
         if [ -f "${unittest_disabled}" ]; then
           GTEST_FILTER="GTEST_FILTER=-$(cat "${unittest_disabled}" | tr '\n' ':')"
           echo "disabled unit test list:"
           cat "${unittest_disabled}"
         fi
         hdc shell "LD_LIBRARY_PATH=${HOS_TMPDIR} ${GTEST_FILTER} ${DEVICE_MUSL_LINKER} ${TARGET_UNIT_TEST_DIR}/${testname}" || EXIT_CODE=$?
       done
     done

 LIT_FILTER="${RUN_TESTS}" ninja -v check-asan || EXIT_CODE=$?
 LIT_FILTER="${RUN_TESTS}" ninja -v check-asan-dynamic || EXIT_CODE=$?
